<?php

namespace App\Http\Controllers\Tenant;

use App\Http\Controllers\Controller;
use App\Http\Requests\Tenant\Settlement\BatchPayRequest;
use App\Jobs\SettlementBatchPayJob;
use App\Jobs\VerifySettlementFourElementsJob;
use App\Jobs\CalculateSettlementTaxJob;
use App\Models\Settlement;
use App\Models\SubSettlement;
use App\Models\Tenant;
use App\Models\Task;
use App\Models\TaskApplication;
use App\Models\LandingCompany;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;

class SettlementController extends Controller
{
    /**
     * 获取结算单列表
     */
    public function index(Request $request)
    {
        $query = Settlement::where('tenant_id', $request->user()->tenant_id)
                    ->with(['task'])
                    ->withSum('subSettlements as tax_total', 'tax')
                    ->withSum('subSettlements as total_required_balance', 'required_balance');

        // 按结算单ID搜索 (支持完整ID或编号)
        if ($request->filled('settlement_id')) {
            $settlementId = $request->settlement_id;
            $query->where(function($q) use ($settlementId) {
                $q->where('id', 'like', "%{$settlementId}%")
                  ->orWhere('settlement_number', 'like', "%{$settlementId}%");
            });
        }

        // 按结算单名称搜索
        if ($request->filled('settlement_name')) {
            $query->where('settlement_name', 'like', "%{$request->settlement_name}%");
        }

        // 按任务筛选
        if ($request->filled('task_id')) {
            $query->where('task_id', $request->task_id);
        }

        // 按状态筛选
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        // 按创建时间范围筛选
        if ($request->filled('start_date')) {
            $query->whereDate('created_at', '>=', $request->start_date);
        }
        if ($request->filled('end_date')) {
            $query->whereDate('created_at', '<=', $request->end_date);
        }

        // 排序
        $sortBy = $request->get('sort_by', 'created_at');
        $sortOrder = $request->get('sort_order', 'desc');
        $query->orderBy($sortBy, $sortOrder);

        $settlements = $query->paginate($request->get('per_page', 15));

        // 为每个结算单添加额外信息
        $settlements->getCollection()->transform(function ($settlement) {
            // 添加任务名称
            $settlement->task_name = $settlement->task ? $settlement->task->name : '-';
            
            // 添加状态显示名
            $settlement->status_display = $settlement->getStatusDisplayAttribute();
            
            // 添加成功率
            $settlement->success_rate = $settlement->getSuccessRateAttribute();
            $settlement->amount_success_rate = $settlement->getAmountSuccessRateAttribute();
            $settlement->tax_total = round((float) ($settlement->tax_total ?? 0), 2);
            $settlement->total_required_balance = round((float) ($settlement->total_required_balance ?? 0), 2);
            
            // 移除完整的task关系以减少响应大小
            unset($settlement->task);
            
            return $settlement;
        });

        return response()->json([
            'code' => 0,
            'message' => '获取结算单列表成功',
            'data' => $settlements
        ]);
    }

    /**
     * 获取任务列表 (用于下拉选择框)
     */
    public function getTasks(Request $request)
    {
        $tenantId = $request->user()->tenant_id;

        $tasks = Task::where('tenant_id', $tenantId)
                    ->where('status', 'active')
                    ->select('id', 'name')
                    ->get();

        return response()->json([
            'code' => 0,
            'message' => '获取任务列表成功',
            'data' => $tasks
        ]);
    }

    /**
     * 创建结算单
     */
    public function store(Request $request)
    {
        $user = $request->user();
        $tenantId = $user->tenant_id ?? 0;

        Log::info('Tenant settlement store request received', [
            'tenant_id' => $tenantId,
            'user_id' => $user->id ?? null,
            'payload' => $request->only([
                'task_id',
                'settlement_name',
                'landing_company',
            ]),
        ]);

        $validator = Validator::make($request->all(), [
            'task_id' => 'required|exists:tasks,id',
            'settlement_name' => 'nullable|string|max:200',
            'landing_company' => 'required|string|max:200',
            'settlement_file' => 'required|file|mimes:xlsx,xls|max:20480',
            'deliverable_file' => 'nullable|file|max:51200',
            'remarks' => 'nullable|string',
        ]);

        if ($validator->fails()) {
            $errors = $validator->errors()->toArray();
            $message = $this->buildErrorMessage($errors);

            Log::warning('Tenant settlement store validation failed', [
                'tenant_id' => $tenantId,
                'user_id' => $user->id ?? null,
                'errors' => $errors,
            ]);

            return response()->json([
                'code' => 422,
                'message' => $message ? '参数验证失败：' . $message : '参数验证失败',
                'data' => ['errors' => $errors],
            ], 422);
        }

        $task = Task::where('tenant_id', $tenantId)
            ->with('tenant')
            ->findOrFail($request->input('task_id'));
        $settlementFile = $request->file('settlement_file');
        $deliverableFile = $request->file('deliverable_file');

        $settlementName = trim((string) $request->input('settlement_name', ''));
        if ($settlementName === '') {
            $baseName = trim((string) ($task->name ?: '结算')); 
            $settlementName = sprintf('%s结算单', $baseName);
        }

        $serviceFeeRate = 0.0;
        if ($task->tenant) {
            $tenantRate = (float) ($task->tenant->service_fee_rate ?? 0);
            if ($tenantRate < 0 || $tenantRate > 1) {
                throw ValidationException::withMessages([
                    'tenant' => ['租户服务费比例配置不合法，请联系管理员处理'],
                ]);
            }
            $serviceFeeRate = $tenantRate;
        }

        $timestamp = (int) (microtime(true) * 1000);
        $taskDirectory = sprintf('tasks/%s', $task->id);

        $storageDisk = config('settlement.storage_disk', config('filesystems.default'));
        $availableDisks = array_keys(config('filesystems.disks', []));
        if (! in_array($storageDisk, $availableDisks, true)) {
            $storageDisk = config('filesystems.default', 'public');
        }
        if ($storageDisk === 'cos') {
            $cosConfig = config('filesystems.disks.cos', []);
            $requiredCosKeys = ['key', 'secret', 'bucket', 'endpoint', 'region'];
            foreach ($requiredCosKeys as $cosKey) {
                if (empty($cosConfig[$cosKey])) {
                    $storageDisk = config('filesystems.default', 'public');
                    break;
                }
            }
        }
        $storage = Storage::disk($storageDisk);

        $settlementFilename = sprintf('%s_结算单_%s.%s', $task->id, $timestamp, $settlementFile->getClientOriginalExtension() ?: 'xlsx');
        $storedSettlementPath = $storage->putFileAs($taskDirectory, $settlementFile, $settlementFilename, ['visibility' => 'private']);
        if (! $storedSettlementPath) {
            Log::error('Tenant settlement store settlement file upload failed', [
                'tenant_id' => $tenantId,
                'user_id' => $user->id ?? null,
                'task_id' => $task->id,
                'storage_disk' => $storageDisk,
            ]);

            return response()->json([
                'code' => 500,
                'message' => '结算单上传失败，请稍后重试',
                'data' => null,
            ], 500);
        }

        $storedDeliverablePath = null;
        if ($deliverableFile) {
            $deliverableFilename = sprintf('%s_交付物_%s.%s', $task->id, $timestamp, $deliverableFile->getClientOriginalExtension() ?: $deliverableFile->extension());
            $storedDeliverablePath = $storage->putFileAs($taskDirectory, $deliverableFile, $deliverableFilename, ['visibility' => 'private']);
        }

        $parsedRows = $this->parseSettlementWorkbook($storage, $storedSettlementPath);
        if ($parsedRows['total_count'] === 0) {
            $storage->delete($storedSettlementPath);
            if ($storedDeliverablePath) {
                $storage->delete($storedDeliverablePath);
            }

            Log::warning('Tenant settlement store parsed empty settlement workbook', [
                'tenant_id' => $tenantId,
                'user_id' => $user->id ?? null,
                'task_id' => $task->id,
                'stored_settlement_path' => $storedSettlementPath,
            ]);

            return response()->json([
                'code' => 422,
                'message' => '结算单文件中未找到有效的结算数据',
                'data' => null,
            ], 422);
        }

        $landingCompanyValue = $request->input('landing_company');
        $landingCompanyId = is_numeric($landingCompanyValue) ? (int) $landingCompanyValue : null;
        $landingCompanyName = (string) $landingCompanyValue;
        if ($landingCompanyId) {
            $landingCompanyModel = LandingCompany::find($landingCompanyId);
            if ($landingCompanyModel) {
                $landingCompanyName = $landingCompanyModel->name;
            }
        }

        $uploadedFiles = array_filter([
            'settlement' => [
                'disk' => $storageDisk,
                'path' => $storedSettlementPath,
                'original_name' => $settlementFile->getClientOriginalName(),
            ],
            'deliverable' => $storedDeliverablePath ? [
                'disk' => $storageDisk,
                'path' => $storedDeliverablePath,
                'original_name' => $deliverableFile ? $deliverableFile->getClientOriginalName() : null,
            ] : null,
            'landing_company_id' => $landingCompanyId,
            'row_count' => $parsedRows['total_count'],
            'total_amount' => $parsedRows['total_amount'],
            'service_fee_rate' => $serviceFeeRate,
        ], function ($value) {
            return $value !== null;
        });

        DB::beginTransaction();

        try {
            $settlement = Settlement::create([
                'settlement_name' => $settlementName,
                'tenant_id' => $tenantId,
                'task_id' => $task->id,
                'landing_company' => $landingCompanyName,
                'total_amount' => $parsedRows['total_amount'],
                'success_amount' => 0,
                'total_count' => $parsedRows['total_count'],
                'success_count' => 0,
                'status' => Settlement::STATUS_PENDING_VERIFY,
                'deliverables' => $storedDeliverablePath,
                'uploaded_files' => $uploadedFiles,
                'remarks' => $request->input('remarks'),
                'created_by' => $user->id,
            ]);

            $totalServiceFee = 0.0;
            $totalRequiredBalance = 0.0;

            foreach ($parsedRows['items'] as $row) {
                $application = $this->resolveApplicationForRow($task, $row);
                $freelancerModel = $application->freelancer;

                $preSettlementAmount = (float) $row['amount'];
                $serviceFee = round($preSettlementAmount * $serviceFeeRate, 2);
                $commission = round($preSettlementAmount, 2);

                $totalServiceFee += $serviceFee;
                $totalRequiredBalance += $preSettlementAmount + $serviceFee;

                SubSettlement::create([
                    'tenant_id' => $tenantId,
                    'settlement_id' => $settlement->id,
                    'freelancer_id' => $freelancerModel->id,
                    'freelancer_name' => $freelancerModel->name,
                    'freelancer_phone' => $freelancerModel->phone,
                    'freelancer_id_card' => $freelancerModel->id_card,
                    'freelancer_bank_account' => $row['bank_account'] ?: $freelancerModel->bank_account,
                    'freelancer_bank_name' => $freelancerModel->bank_name,
                    'pre_settlement_amount' => $preSettlementAmount,
                    'commission' => $commission,
                    'service_fee' => $serviceFee,
                    'service_fee_rate' => $serviceFeeRate,
                    'tax' => 0,
                    'required_balance' => $preSettlementAmount + $serviceFee,
                    'status' => SubSettlement::STATUS_PENDING_VERIFY,
                    'status_description' => '等待四要素验证',
                    'payment_remarks' => $row['remarks'],
                    'created_by' => $user->id,
                ]);
            }

            $uploadedMeta = $uploadedFiles;
            $uploadedMeta['total_service_fee'] = round($totalServiceFee, 2);
            $settlement->uploaded_files = $uploadedMeta;
            $settlement->total_required_balance = round($totalRequiredBalance, 2);
            $settlement->save();

            DB::commit();

            VerifySettlementFourElementsJob::dispatch($settlement->settlement_number);

            Log::info('Tenant settlement store created successfully', [
                'tenant_id' => $tenantId,
                'user_id' => $user->id ?? null,
                'settlement_id' => $settlement->id,
                'settlement_number' => $settlement->settlement_number,
                'total_count' => $parsedRows['total_count'],
                'total_amount' => $parsedRows['total_amount'],
            ]);

            return response()->json([
                'code' => 0,
                'message' => '结算单创建成功',
                'data' => $settlement->fresh(),
            ], 201);
        } catch (ValidationException $exception) {
            DB::rollBack();

            if ($storedSettlementPath) {
                $storage->delete($storedSettlementPath);
            }
            if ($storedDeliverablePath) {
                $storage->delete($storedDeliverablePath);
            }

            $errors = $exception->errors();
            $message = $this->buildErrorMessage($errors);

            Log::warning('Tenant settlement store validation exception', [
                'tenant_id' => $tenantId,
                'user_id' => $user->id ?? null,
                'task_id' => $request->input('task_id'),
                'errors' => $errors,
            ]);

            return response()->json([
                'code' => 422,
                'message' => $message ?: '参数验证失败',
                'data' => ['errors' => $errors],
            ], 422);
        } catch (\Throwable $exception) {
            DB::rollBack();

            if ($storedSettlementPath) {
                $storage->delete($storedSettlementPath);
            }
            if ($storedDeliverablePath) {
                $storage->delete($storedDeliverablePath);
            }

            Log::error('Tenant settlement store unexpected exception', [
                'tenant_id' => $tenantId,
                'user_id' => $user->id ?? null,
                'task_id' => $request->input('task_id'),
                'exception' => $exception->getMessage(),
                'trace_id' => $request->headers->get('X-Request-Id'),
            ]);

            return response()->json([
                'code' => 500,
                'message' => '结算单创建失败，请稍后重试',
                'data' => ['error' => $exception->getMessage()],
            ], 500);
        }
    }

    public function batchPay(BatchPayRequest $request, string $settlementNumber)
    {
        $tenantId = $request->user()->tenant_id;

        $settlement = Settlement::withCount([
            'subSettlements as pending_submit_count' => function ($query) {
                $query->where('status', SubSettlement::STATUS_PENDING_SUBMIT);
            },
        ])->where('tenant_id', $tenantId)
            ->where('settlement_number', $settlementNumber)
            ->first();

        if (! $settlement) {
            return response()->json([
                'code' => 404,
                'message' => '结算单不存在或不属于当前租户',
                'data' => null,
            ], 404);
        }

        Log::info('Tenant batch pay settlement retrieved', [
            'tenant_id' => $tenantId,
            'settlement' => $settlement->toArray(),
        ]);

        if ($settlement->status !== Settlement::STATUS_PENDING_SUBMIT) {
            return response()->json([
                'code' => 422,
                'message' => '当前结算单状态不允许发放',
                'data' => null,
            ], 422);
        }

        if ($settlement->pending_submit_count === 0) {
            return response()->json([
                'code' => 422,
                'message' => '当前结算单没有待提交的子结算单',
                'data' => null,
            ], 422);
        }

        $tenant = Tenant::find($tenantId);

        if (! $tenant) {
            return response()->json([
                'code' => 404,
                'message' => '租户不存在或无权操作',
                'data' => null,
            ], 404);
        }

        $requiredBalance = SubSettlement::where('settlement_id', $settlement->id)
            ->where('status', SubSettlement::STATUS_PENDING_SUBMIT)
            ->sum('required_balance');

        $accountBalance = $tenant->account_balance ?? 0;

        if (bccomp((string) $accountBalance, (string) $requiredBalance, 2) < 0) {
            Log::warning('Tenant batch pay blocked due to insufficient balance', [
                'tenant_id' => $tenantId,
                'settlement_id' => $settlement->id,
                'account_balance' => $accountBalance,
                'required_balance' => $requiredBalance,
            ]);

            return response()->json([
                'code' => 422,
                'message' => '当前账户余额不足以覆盖所需资金，请先充值',
                'data' => [
                    'account_balance' => round((float) $accountBalance, 2),
                    'required_balance' => round((float) $requiredBalance, 2),
                ],
            ]);
        }

        if (SubSettlement::where('settlement_id', $settlement->id)
            ->whereIn('status', [
                SubSettlement::STATUS_PENDING_DISTRIBUTE,
                SubSettlement::STATUS_DISTRIBUTING,
            ])->exists()) {
            return response()->json([
                'code' => 409,
                'message' => '该结算单已经存在发放任务进行中',
                'data' => null,
            ]);
        }

        SettlementBatchPayJob::dispatch(
            $settlement->id,
            $settlement->settlement_number,
            $tenantId,
            $request->user()->id
        );

        return response()->json([
            'code' => 0,
            'message' => '批量发放任务已提交',
            'data' => null,
        ]);
    }

    /**
     * 获取单个结算单详情
     */
    public function show(Request $request, $id)
    {
        try {
            $tenantId = $request->user()->tenant_id;
            
            // 手动查找结算单，确保租户隔离
            $settlement = Settlement::where('tenant_id', $tenantId)
                ->where('id', $id)
                ->first();
                
            if (! $settlement) {
                return response()->json([
                    'code' => 404,
                    'message' => '结算单不存在或无权访问',
                    'data' => null,
                ], 404);
            }
            
            // 加载关联数据
            $settlement->load(['task', 'createdBy', 'submittedBy', 'processedBy']);
            
            // 确保settlement_number存在（仅当记录存在时才更新）
            if (empty($settlement->settlement_number) && $settlement->exists) {
                // 生成结算单编号
                $settlementNumber = 'SETTLE' . date('YmdHis') . str_pad($settlement->id, 6, '0', STR_PAD_LEFT);
                $settlement->update(['settlement_number' => $settlementNumber]);
                $settlement->settlement_number = $settlementNumber; // 更新内存中的值
            } elseif (empty($settlement->settlement_number)) {
                // 如果记录不存在，生成一个临时编号用于显示
                $settlement->settlement_number = 'SETTLE' . date('YmdHis') . str_pad($settlement->id ?? 0, 6, '0', STR_PAD_LEFT);
            }
            
            // 构建返回数据
            $data = [
                'id' => $settlement->id,
                'settlement_number' => $settlement->settlement_number,
                'settlement_name' => $settlement->settlement_name,
                'tenant_id' => $settlement->tenant_id,
                'task_id' => $settlement->task_id,
                'task_name' => $settlement->task ? $settlement->task->name : null,
                'landing_company' => $settlement->landing_company,
                'total_amount' => $settlement->total_amount,
                'total_required_balance' => $settlement->total_required_balance,
                'success_amount' => $settlement->success_amount,
                'total_count' => $settlement->total_count,
                'success_count' => $settlement->success_count,
                'status' => $settlement->status,
                'status_display' => $settlement->getStatusDisplayAttribute(),
                'deliverables' => $settlement->deliverables,
                'remarks' => $settlement->remarks,
                'uploaded_files' => $settlement->uploaded_files,
                'success_rate' => $settlement->getSuccessRateAttribute(),
                'amount_success_rate' => $settlement->getAmountSuccessRateAttribute(),
                'created_at' => $settlement->created_at,
                'updated_at' => $settlement->updated_at,
                'submitted_at' => $settlement->submitted_at,
                'processed_at' => $settlement->processed_at,
                'created_by' => $settlement->created_by,
                'submitted_by' => $settlement->submitted_by,
                'processed_by' => $settlement->processed_by,
                // 关联数据
                'task' => $settlement->task ? [
                    'id' => $settlement->task->id,
                    'name' => $settlement->task->name,
                    'description' => $settlement->task->description ?? null
                ] : null
            ];

            return response()->json([
                'code' => 0,
                'data' => $data,
                'message' => '获取结算单详情成功'
            ]);
            
        } catch (\Exception $e) {
            \Log::error('获取结算单详情失败', [
                'settlement_id' => $settlement->id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            return response()->json([
                'code' => 500,
                'message' => '获取结算单详情失败：' . $e->getMessage(),
                'data' => null,
            ], 500);
        }
    }

    /**
     * 更新结算单信息
     */
    public function update(Request $request, Settlement $settlement)
    {
        $validator = Validator::make($request->all(), [
            'settlement_name' => 'string|max:200',
            'task_id' => 'nullable|exists:tasks,id',
            'landing_company' => 'string|max:200',
            'total_amount' => 'numeric|min:0',
            'success_amount' => 'nullable|numeric|min:0',
            'total_count' => 'integer|min:0',
            'success_count' => 'nullable|integer|min:0',
            'deliverables' => 'nullable|string',
            'remarks' => 'nullable|string'
        ]);

        if ($validator->fails()) {
            return response()->json([
                'code' => 422,
                'message' => '参数验证失败',
                'data' => ['errors' => $validator->errors()],
            ], 422);
        }

        $settlement->update($request->all());

        return response()->json([
            'code' => 0,
            'message' => '结算单信息更新成功',
            'data' => $settlement,
        ]);
    }

    /**
     * 删除结算单
     */
    public function destroy(Request $request, Settlement $settlement)
    {
        if ($settlement->tenant_id !== $request->user()->tenant_id) {
            return response()->json([
                'code' => 403,
                'message' => '无权操作该结算单',
                'data' => null,
            ], 403);
        }

        $lockedStatuses = [
            Settlement::STATUS_DISTRIBUTING,
            Settlement::STATUS_COMPLETED,
            Settlement::STATUS_DISTRIBUTE_FAILED,
            Settlement::STATUS_PARTIAL_FAILED,
            Settlement::STATUS_REFUNDED,
        ];

        if (in_array($settlement->status, $lockedStatuses, true)) {
            return response()->json([
                'code' => 422,
                'message' => '发放中及之后状态的结算单无法删除',
                'data' => null,
            ], 422);
        }

        $settlement->delete();

        return response()->json([
            'code' => 0,
            'message' => '结算单删除成功',
            'data' => null,
        ]);
    }

    /**
     * 提交结算单
     */
    public function submit(Request $request, Settlement $settlement)
    {
        if ($settlement->status !== Settlement::STATUS_PENDING_SUBMIT) {
            return response()->json([
                'code' => 422,
                'message' => '只有待提交状态的结算单才能提交',
                'data' => null,
            ], 422);
        }

        $settlement->submit($request->user()->id);

        return response()->json([
            'code' => 0,
            'message' => '结算单提交成功',
            'data' => $settlement,
        ]);
    }

    /**
     * 取消结算单
     */
    public function cancel(Settlement $settlement)
    {
        if (in_array($settlement->status, [Settlement::STATUS_COMPLETED, Settlement::STATUS_CANCELLED])) {
            return response()->json([
                'code' => 422,
                'message' => '已完成或已取消的结算单无法取消',
                'data' => null,
            ], 422);
        }

        $settlement->cancel();

        return response()->json([
            'code' => 0,
            'message' => '结算单取消成功',
            'data' => $settlement,
        ]);
    }

    /**
     * 触发算税任务
     */
    public function triggerTax(Request $request, string $settlementId)
    {
        $settlement = Settlement::query()->where('id', $settlementId)->first();

        if (! $settlement) {
            return response()->json([
                'code' => 404,
                'message' => '结算单不存在',
                'data' => null,
            ], 404);
        }

        if ($settlement->tenant_id !== $request->user()->tenant_id) {
            return response()->json([
                'code' => 403,
                'message' => '无权操作该结算单',
                'data' => null,
            ], 403);
        }

        $subSettlementsQuery = $settlement->subSettlements();

        if (! $subSettlementsQuery->exists()) {
            return response()->json([
                'code' => 422,
                'message' => '当前结算单没有可算税的子结算单',
                'data' => null,
            ], 422);
        }

        $invalidCount = (clone $subSettlementsQuery)
            ->where('status', '!=', SubSettlement::STATUS_PENDING_TAX)
            ->count();

        if ($invalidCount > 0) {
            return response()->json([
                'code' => 422,
                'message' => '仅支持所有子结算单均为待算税状态时触发算税',
                'data' => ['invalid_count' => $invalidCount],
            ], 422);
        }

        CalculateSettlementTaxJob::dispatch($settlement->id);

        return response()->json([
            'code' => 0,
            'message' => '算税任务已进入队列',
            'data' => ['settlement_id' => $settlement->id],
        ]);
    }

    /**
     * 批量操作
     */
    public function batchAction(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'action' => 'required|in:submit,cancel,delete',
            'ids' => 'required|array|min:1',
            'ids.*' => 'string|exists:settlements,id'
        ]);

        if ($validator->fails()) {
            return response()->json([
                'code' => 422,
                'message' => '参数验证失败',
                'data' => ['errors' => $validator->errors()],
            ], 422);
        }

        $settlements = Settlement::whereIn('id', $request->ids);
        $count = $settlements->count();

        switch ($request->action) {
            case 'submit':
                $settlements->where('status', Settlement::STATUS_PENDING_SUBMIT)
                          ->update([
                              'status' => Settlement::STATUS_DISTRIBUTING,
                              'submitted_at' => now(),
                              'submitted_by' => $request->user()->id
                          ]);
                $message = "已提交 {$count} 个结算单";
                break;
            case 'cancel':
                $settlements->whereNotIn('status', [Settlement::STATUS_COMPLETED, Settlement::STATUS_CANCELLED])
                          ->update(['status' => Settlement::STATUS_CANCELLED]);
                $message = "已取消 {$count} 个结算单";
                break;
            case 'delete':
                $settlements->delete();
                $message = "已删除 {$count} 个结算单";
                break;
        }

        return response()->json([
            'code' => 0,
            'message' => $message,
            'data' => [
                'affected' => $count,
                'action' => $request->action,
            ],
        ]);
    }

    /**
     * 获取结算单统计信息
     */
    public function getStatistics(Request $request)
    {
        $tenantId = $request->user()->tenant_id;

        $statusCounts = [];
        foreach ([
            Settlement::STATUS_PENDING_VERIFY,
            Settlement::STATUS_VERIFYING,
            Settlement::STATUS_VERIFY_FAILED,
            Settlement::STATUS_PENDING_TAX,
            Settlement::STATUS_PENDING_SUBMIT,
            Settlement::STATUS_PENDING_DISTRIBUTE,
            Settlement::STATUS_DISTRIBUTING,
            Settlement::STATUS_COMPLETED,
            Settlement::STATUS_CANCELLED,
            Settlement::STATUS_DISTRIBUTE_FAILED,
            Settlement::STATUS_PARTIAL_FAILED,
            Settlement::STATUS_REFUNDED,
        ] as $status) {
            $statusCounts[$status] = Settlement::byTenant($tenantId)->byStatus($status)->count();
        }

        $stats = [
            'total' => Settlement::byTenant($tenantId)->count(),
            'status_counts' => $statusCounts,
            'total_amount' => Settlement::byTenant($tenantId)->sum('total_amount'),
            'success_amount' => Settlement::byTenant($tenantId)->sum('success_amount')
        ];

        return response()->json([
            'code' => 0,
            'message' => '获取结算统计成功',
            'data' => $stats,
        ]);
    }

    private function parseSettlementWorkbook($storage, string $path): array
    {
        $tempPath = tempnam(sys_get_temp_dir(), 'settlement_');
        $stream = $storage->readStream($path);
        if (! $stream) {
            throw new \RuntimeException('无法读取结算单文件');
        }

        $tempHandle = fopen($tempPath, 'w+');
        stream_copy_to_stream($stream, $tempHandle);
        fclose($stream);
        fclose($tempHandle);

        $reader = new Xlsx();
        $reader->setReadDataOnly(true);
        $spreadsheet = $reader->load($tempPath);
        unlink($tempPath);

        $worksheet = $spreadsheet->getActiveSheet();
        $highestRow = $worksheet->getHighestDataRow();

        $columnMap = [
            'name' => 'A',
            'phone' => 'B',
            'id_card' => 'C',
            'bank_account' => 'D',
            'amount' => 'E',
            'remarks' => 'F',
        ];

        $items = [];
        $totalAmount = 0.0;

        for ($row = 2; $row <= $highestRow; $row++) {
            $rawValues = [];
            foreach ($columnMap as $field => $column) {
                $cell = $worksheet->getCell($column . $row);
                $cellValue = $cell ? $cell->getFormattedValue() : '';
                if (is_string($cellValue)) {
                    $cellValue = trim($cellValue);
                }
                $rawValues[$field] = $cellValue;
            }

            if ($this->rowIsEmpty($rawValues)) {
                continue;
            }

            $amount = $this->normalizeAmount($rawValues['amount']);

            $items[] = [
                'row' => $row,
                'name' => trim((string) $rawValues['name']),
                'phone' => preg_replace('/\s+/', '', (string) $rawValues['phone']),
                'id_card' => trim((string) $rawValues['id_card']),

                'bank_account' => preg_replace('/\s+/', '', (string) $rawValues['bank_account']),
                'amount' => $amount,
                'remarks' => trim((string) $rawValues['remarks']),
            ];

            $totalAmount += $amount;
        }

        $spreadsheet->disconnectWorksheets();
        unset($spreadsheet);

        return [
            'items' => $items,
            'total_count' => count($items),
            'total_amount' => $totalAmount,
        ];
    }

    private function rowIsEmpty(array $row): bool
    {
        foreach ($row as $value) {
            if (trim((string) $value) !== '') {
                return false;
            }
        }

        return true;
    }

    private function normalizeAmount($value): float
    {
        if (is_numeric($value)) {
            return round((float) $value, 2);
        }

        $clean = preg_replace('/[^0-9.\-]/', '', (string) $value);
        if ($clean === '' || $clean === '-' || $clean === '.') {
            return 0.0;
        }

        return round((float) $clean, 2);
    }

    private function resolveApplicationForRow(Task $task, array $row): TaskApplication
    {
        $phone = $row['phone'] ?? null;
        $idCard = $row['id_card'] ?? null;

        if (! $phone && ! $idCard) {
            throw ValidationException::withMessages([
                'settlement_file' => ["第 {$row['row']} 行缺少手机号或身份证号，无法匹配报名记录"],
            ]);
        }

        $applicationQuery = TaskApplication::with('freelancer')
            ->where('tenant_id', $task->tenant_id)
            ->where('task_id', $task->id)
            ->where('status', 'approved');

        $applicationQuery->where(function ($query) use ($phone, $idCard) {
            if ($phone) {
                $query->orWhere('phone', $phone);
            }
            if ($idCard) {
                $query->orWhere('id_card', $idCard);
            }
        });

        $application = $applicationQuery->first();

        if (! $application) {
            Log::warning('Settlement upload row missing application', [
                'tenant_id' => $task->tenant_id,
                'task_id' => $task->id,
                'row_number' => $row['row'],
                'name' => $row['name'] ?? null,
                'phone' => $row['phone'] ?? null,
                'id_card' => $row['id_card'] ?? null,
            ]);

            throw ValidationException::withMessages([
                'settlement_file' => ["第 {$row['row']} 行未找到对应的签约报名记录"],
            ]);
        }

        if (! $application->freelancer) {
            Log::warning('Settlement upload row missing freelancer relation', [
                'tenant_id' => $tenantId,
                'task_id' => $task->id,
                'application_id' => $application->id,
                'row_number' => $row['row'],
                'name' => $row['name'] ?? null,
            ]);

            throw ValidationException::withMessages([
                'settlement_file' => ["第 {$row['row']} 行报名记录缺少关联的自由职业者，请联系管理员处理"],
            ]);
        }

        return $application;
    }

    private function buildErrorMessage(array $errors): string
    {
        $messages = [];

        foreach ($errors as $fieldErrors) {
            if (is_array($fieldErrors)) {
                foreach ($fieldErrors as $message) {
                    if ($message !== null && $message !== '') {
                        $messages[] = (string) $message;
                    }
                }
            } elseif (is_string($fieldErrors) && $fieldErrors !== '') {
                $messages[] = $fieldErrors;
            }
        }

        $messages = array_unique($messages);

        return implode('；', $messages);
    }
}
